package com.cgx.websocket.handler;

import com.alibaba.fastjson.JSON;
import com.cgx.entity.message.Session;
import com.cgx.entity.message.SessionUser;
import com.cgx.service.MessageService;
import com.cgx.utils.ByteBufferUtils;
import com.cgx.utils.UUIDUtils;
import com.cgx.utils.UrlUtils;
import com.cgx.vo.ResultVo;
import com.cgx.vo.websocket.MessageVo;
import com.cgx.vo.websocket.MqMessageVo;
import com.cgx.websocket.MyWebSocketHandler;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author chenguanxin
 * @date 2021-05-20 21:12
 */
@Component
public class WebSocketEventHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private MessageService messageService;

//    ws://127.0.0.1:9092/webSocket?userId=123
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String url = session.getUri().toString();
        UrlUtils.UrlEntity entity = UrlUtils.parse(url);
        String userId = entity.params.get("userId");
        if (StringUtils.isNotBlank(userId)) {
            logger.info("WebSocketEventHandler-afterConnectionEstablished-userId: " + userId);
            MyWebSocketHandler.SESSION_MAP.put(userId, session);
        }
    }

    public void afterConnectionClosed(WebSocketSession session, CloseStatus arg1) throws Exception {
        String url = session.getUri().toString();
        UrlUtils.UrlEntity entity = UrlUtils.parse(url);
        String userId = entity.params.get("userId");
        if (StringUtils.isNotBlank(userId)) {
            logger.info("WebSocketEventHandler-afterConnectionClosed-userId: " + userId);
            MyWebSocketHandler.SESSION_MAP.remove(userId);
        }
    }

    //  { "sessionId": "97abdd54ddea4b6e84464890b4a9f3d5", "fromUserId": "123", "type": 1, "content": "test" }
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
        Object payload = message.getPayload();
        String messageStr = "";
        if (payload instanceof String) {
            messageStr = (String) payload;
        } else if (payload instanceof ByteBuffer) {
            messageStr = ByteBufferUtils.getString((ByteBuffer) payload);
        }
        System.out.println("message ==>" + messageStr);
        if (StringUtils.isNotBlank(messageStr)) {
            MessageVo messageVo = JSON.parseObject(messageStr, MessageVo.class);
            if (messageVo != null) {
                if (-1 == messageVo.getType()) {
                    return;
                }else if (1 == messageVo.getType()) {
                    sendMessageBySessionType(messageVo);
                }
            }
        }
    }

    private void sendMessageBySessionType(MessageVo messageVo) {
        String processId = UUIDUtils.getUUID();
        messageVo.setProcessId(processId);
        Map<String, ResultVo> resultVoMap = messageService.saveMessage(Collections.singletonList(messageVo));
        if (resultVoMap.containsKey(processId) && resultVoMap.get(processId).getResult() && resultVoMap.get(processId).getData() != null) {
            Object sendMessageObj = resultVoMap.get(processId).getData();
            String sessionId = messageVo.getSessionId();
            List<Session> sessionList = messageService.getSessionBySessionId(Collections.singletonList(sessionId));
            if (CollectionUtils.isNotEmpty(sessionList)) {
                Session session = sessionList.get(0);
                if ("1".equals(session.getSessionType())) {
                    List<SessionUser> sessionUserList = messageService.getSessionUserBySessionId(Collections.singletonList(sessionId));
                    if (CollectionUtils.isNotEmpty(sessionUserList)) {
                        for (SessionUser sessionUser : sessionUserList) {
                            if (!sessionUser.getUserId().equals(messageVo.getFromUserId())) {
                                WebSocketSession webSocketSession = MyWebSocketHandler.SESSION_MAP.get(sessionUser.getUserId());
                                if (webSocketSession != null) {
                                    try {
                                        webSocketSession.sendMessage(new TextMessage(JSON.toJSONString(sendMessageObj)));
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
